Skip to main content

Solid Principles

The SOLID principles are a set of five design principles intended to make object-oriented software designs more understandable, flexible, and maintainable

The SOLID principle helps in reducing tight coupling. Tight coupling means a group of classes are highly dependent on one another which you should avoid in your code.

Opposite of tight coupling is loose coupling and your code is considered as a good code when it has loosely-coupled classes. Loosely coupled classes minimize changes in your code, helps in making code more reusable, maintainable, flexible and stable.

Single Responsibility Principle (SRP)​

A class should have only one reason to change, meaning it should only have one job or responsibility.

Open/Closed Principle (OCP)​

Software entities (classes, modules, functions, etc.) should be open for extension but closed for modification.

Liskov Substitution Principle (LSP)​

Objects of a superclass should be replaceable with objects of a subclass without affecting the correctness of the program.

Interface Segregation Principle (ISP)​

Clients should not be forced to depend on interfaces they do not use. Instead of one large interface, multiple smaller and more specific interfaces are preferable.

Dependency Inversion Principle (DIP)​

High-level modules should not depend on low-level modules. Both should depend on abstractions. Abstractions should not depend on details, and details should depend on abstractions.

Example: Suppose a class BackendDeveloper directly depends on another class Database. This creates tight coupling between the two classes.

Violation of DIP:

class Database {
public void connect() {
System.out.println("Connected to database");
}
}

class BackendDeveloper {
private Database database;

public BackendDeveloper(Database database) {
this.database = database;
}

public void develop() {
database.connect();
System.out.println("Developing backend...");
}
}

Applying DIP:

interface DatabaseConnection {
void connect();
}

class MySQLConnection implements DatabaseConnection {
public void connect() {
System.out.println("Connected to MySQL database");
}
}

class BackendDeveloper {
private DatabaseConnection databaseConnection;

public BackendDeveloper(DatabaseConnection databaseConnection) {
this.databaseConnection = databaseConnection;
}

public void develop() {
databaseConnection.connect();
System.out.println("Developing backend...");
}
}